package com.example.baseutils.usb;

import android.hardware.usb.UsbDevice;
import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;


public class UsbDeviceBusFinder {
    private static final String TAG = "UsbDeviceBusFinder";
    private static final String BUS_PARNET_PATH       =  "/sys/bus/usb/devices";
    private static final String ID_VENDOR_FILE_NAME   = "idVendor";
    private static final String ID_PRODUCT_FILE_NAME  = "idProduct";
    private static final String ID_BUS_NUM            = "busnum";
    private static final String ID_DEV_NUM            = "devnum";

    public static UsbBusInfo find(final String bus){
        final List<UsbBusInfo> busInfos = list(bus);
        if(!busInfos.isEmpty()){
            return busInfos.get(0);
        }
        return null;
    }

    public static List<UsbBusInfo> find(final int vendorId, final int productId){
        final List<UsbBusInfo> busInfos = list();
        if(!busInfos.isEmpty()){
            for(int i = 0; i < busInfos.size(); i++){
                final UsbBusInfo info = busInfos.get(i);
                if(info.getVendorId() != vendorId &&
                        info.getProductId() != productId){
                    busInfos.remove(i);
                    i--;
                }
            }
            for (UsbBusInfo info:
                    busInfos) {
                Log.e(TAG, "find: " + info.toString());
            }
        }

        return busInfos;
    }

    public static UsbBusInfo find(final String bus, final int vendorId, final int productId){
        final List<UsbBusInfo> busInfos = list();
        if(!busInfos.isEmpty()){
            int index = -1;
            for(int i = 0; i < busInfos.size(); i++){
                final UsbBusInfo info = busInfos.get(i);
                if(info.getVendorId() == vendorId &&
                   info.getProductId() == productId &&
                   info.getBus().equals(bus)){
                   index = i;
                   break;
                }
            }

            if(index > -1){
                return busInfos.get(index);
            }
        }

        return null;
    }

    public static UsbBusInfo find(final int vendorId, final int productId,
                                  final int busnum, final int devnum){
        final List<UsbBusInfo> busInfos = list();
        if(!busInfos.isEmpty()){
            int index = -1;
            for(int i = 0; i < busInfos.size(); i++){
                final UsbBusInfo info = busInfos.get(i);
                if(info.getVendorId()  == vendorId &&
                   info.getProductId() == productId &&
                   info.getBusNum() == busnum && info.getDevNum() == devnum){
                    index = i;
                    break;
                }
            }

            if(index > -1){
                return busInfos.get(index);
            }
        }

        return null;
    }
    /**
     * 列出所有接在板子上的USB设备的BUS信息
     * @return
     */
    public static List<UsbBusInfo> list(){
        final List<File> files = new ArrayList<>();
        //找到含有idVendor、idProduct、busnum和devnum文件的File
        findVendorAndProduct(files);
        return parseFiles(files);
    }

    /**
     * 获取bus下的UsbBusInfo
     * @param bus
     * @return
     */
    private static List<UsbBusInfo> list(final String bus){
        final List<File> files = new ArrayList<>();
        //找到含有idVendor、idProduct、busnum和devnum文件的File
        findVendorAndProductForBus(bus, files);
        return parseFiles(files);
    }

    private static List<UsbBusInfo> parseFiles(final List<File> files){
        List<UsbBusInfo> usbBusInfos = new ArrayList<>();
        final int offset = 4;
        for(int i = 0; i < files.size(); i += offset){
            final UsbBusInfo busInfo = new UsbBusInfo();
            final File parentFile = files.get(i).getParentFile();
            if(parentFile != null){
                final String parentDir = parentFile.getName();
                Log.e(TAG, "list: parentDir ---> " + parentDir);
                busInfo.setBus(parentDir);
            }
            for(int j = 0; j < offset; j++){
                File file = files.get(i + j);
                final String path = file.getAbsolutePath();
                Log.e(TAG, "list: path ---> " + path);
                try {
                    final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                    String value = br.readLine(); //value是16进制 不带0x
                    Log.e(TAG, "list: value--->" + value);
                    if(value != null){
                        if(file.getName().equals(ID_VENDOR_FILE_NAME)){
                            //16进制字符串转int型
                            final int id = Integer.parseInt(value, 16);
                            busInfo.setVendorId(id);
                        }else if(file.getName().equals(ID_PRODUCT_FILE_NAME)){
                            //16进制字符串转int型
                            final int id = Integer.parseInt(value, 16);
                            busInfo.setProductId(id);
                        }else if(file.getName().equals(ID_BUS_NUM)){
                            final int num = Integer.parseInt(value);
                            busInfo.setBusNum(num);
                        }else if(file.getName().equals(ID_DEV_NUM)){
                            final int num = Integer.parseInt(value);
                            busInfo.setDevNum(num);
                        }
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            usbBusInfos.add(busInfo);
        }
        for (int i = 0; i < usbBusInfos.size(); i++) {
            Log.e(TAG, "list: " + usbBusInfos.get(i).toString());
        }
        return usbBusInfos;
    }

    public static UsbBusInfo parseUsbDevice(UsbDevice usbDevice){
        UsbBusInfo usbBusInfo = null;
        if(usbDevice != null){
            //获得vendorId和productId
            final int vendorId  = usbDevice.getVendorId();
            final int productId = usbDevice.getProductId();
            //解析设备名获取busnum和devnum
            final String name = usbDevice.getDeviceName();
            final String[] v = !TextUtils.isEmpty(name) ? name.split("/") : null;
            int busnum = 0;
            int devnum = 0;
            if (v != null) {
                busnum = Integer.parseInt(v[v.length - 2]);
                devnum = Integer.parseInt(v[v.length - 1]);
            }
            usbBusInfo = find(vendorId, productId, busnum, devnum);
        }

        return usbBusInfo;
    }

    private static void findVendorAndProduct(final List<File> fileList){
        File file = new File(BUS_PARNET_PATH);
        if(file.exists()){
            final File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    final String name = pathname.getName();
                    return !name.contains("usb");
                }
            });
            if(files != null){
                for (File f:
                        files) {
                    Log.e(TAG, "findVendorAndProduct: f-->" + f.getAbsolutePath());
                    //寻找每个文件下的idVendor和idProduct
                    File[] files1 = f.listFiles(createFileFilter());
                    if(files1 != null){
                        for(int i = 0; i < files1.length; i++){
                            fileList.add(files1[i]);
                            Log.e(TAG, "findVendorAndProduct: " + files1[i].getAbsolutePath());
                        }
                    }
                }
            }
        }
    }

    private static void findVendorAndProductForBus(final String bus, final List<File> fileList){
        File file = new File(BUS_PARNET_PATH + File.separator + bus);
        if(file.exists() && file.isDirectory()){
            //寻找每个文件下的idVendor和idProduct
            File[] files = file.listFiles(createFileFilter());
            if(files != null){
                for(int i = 0; i < files.length; i++){
                    fileList.add(files[i]);
                    Log.e(TAG, "findVendorAndProduct: " + files[i].getAbsolutePath());
                }
            }
        }
    }

    private static FileFilter createFileFilter(){
        return new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                final String name = pathname.getName();
                return  name.equals(ID_VENDOR_FILE_NAME) ||
                        name.equals(ID_PRODUCT_FILE_NAME) ||
                        name.equals(ID_BUS_NUM) ||
                        name.equals(ID_DEV_NUM);
            }
        };
    }
}
